<script setup lang="ts">
import { computed, reactive, ref, toRaw } from 'vue'
import type { FormInstance } from 'element-plus'
import { User, Lock, InfoFilled, Odometer } from '@element-plus/icons-vue'
import { useRouter } from 'vue-router'

import { useEventListener } from '@vueuse/core'
import illustration from '@/assets/img/login/illustration.svg?component'
import loginBg from '@/assets/img/login/login-bg.svg?component'
import logo from '@/assets/img/login/logo.webp'
import Motion from '@/utils/motion'
import { loginRules } from './utils/rule'
import { operates, thirdParty } from './utils/enums'
import { Message } from '@/utils/message'
import { ReImageVerify } from '@/components/ReImageVerify'
import { useUserStoreHook } from '@/store/modules/user'
import { useDataThemeChange } from '@/layout/hooks/useDataThemeChange'
import { useLangChange } from '@/layout/hooks/useLangChange'
import { useI18n } from 'vue-i18n'

import { debounce } from 'lodash-es'
const router = useRouter()
// 国际化
const { t } = useI18n()
const { locale, transferLang } = useLangChange()

// 主题
const {
  dataTheme,
  epThemeColor,
  themeColors,
  setEpThemeColor,
  dataThemeChange
} = useDataThemeChange()
dataThemeChange()
const themeWidth = themeColors.value.length * 36 + 20 + 'px'

// 登录
const imgCode = computed({
  get() {
    return useUserStoreHook().verificationCode
  },
  set(val) {
    useUserStoreHook().SET_VERIFICATION_CODE(val)
  }
})
const loading = ref(false)
const disabled = ref(false)
const loginFormRef = ref<FormInstance>()
const loginForm = reactive({
  name: 'liukun',
  password: '123456!',
  verifyCode: '',
  expiresInDays: 1
})

const onLogin = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate(valid => {
    if (valid) {
      loading.value = true
      useUserStoreHook()
        .loginByUsername(loginForm)
        .then(() => {
          router.push('/welcome')
          Message.success(t('login.success'))
        })
        .catch(err => {
          Message.error(err.message)
        })
        .finally(() => (loading.value = false))
    }
  })
}
const immediateDebounce: any = debounce(formRef => onLogin(formRef), 1000, {
  leading: true
})

useEventListener(document, 'keypress', ({ code }) => {
  if (
    ['Enter', 'NumpadEnter'].includes(code) &&
    !disabled.value &&
    !loading.value
  )
    immediateDebounce(loginFormRef.value)
})
</script>
<template>
  <div class="w-full h-full reactive easy-login overflow-hidden">
    <div class="easy-bg">
      <component :is="toRaw(loginBg)" class="re-svg" />
    </div>
    <Motion :delay="50">
      <div class="flex-c absolute left-20 top-8">
        <img class="h-10" :src="logo" alt="logo" />
        <span class="easy-logo ml-2">Easy Admin</span>
      </div>
    </Motion>

    <div class="flex-c absolute right-5 top-5 login-tool">
      <!-- 颜色选择器 -->

      <div class="flex-c color-picker mr-3">
        <div class="color-box">
          <span
            v-for="(item, index) in themeColors"
            :key="index"
            class="mr-2"
            :class="item.color === epThemeColor ? 'icon-check' : ''"
            :style="{ background: item.color }"
            @click="setEpThemeColor(item.color)"
          />
        </div>

        <!-- 主题 -->
        <el-button link class="icon-color" />
      </div>
      <el-dropdown @command="transferLang">
        <el-button link class="icon-translate mr-3" />
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item command="zh">
              <i :class="{ 'icon-check': locale === 'zh' }" />
              简体中文
            </el-dropdown-item>
            <el-dropdown-item command="en">
              <i :class="{ 'icon-check': locale === 'en' }" />
              English
            </el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
      <el-button
        link
        :class="dataTheme ? 'icon-moon' : 'icon-sunny'"
        @click="dataThemeChange(dataTheme ? 'light' : 'dark')"
      />
    </div>

    <div class="login-container">
      <Motion :delay="200" class="login-illustration">
        <div>
          <component :is="toRaw(illustration)" />
          <h2 class="text-white">{{ t('login.tip') }}</h2>
        </div>
      </Motion>

      <div class="login-box">
        <div class="w-[380px]">
          <Motion :delay="50" direction="right">
            <h1 class="text-left mb-8 text-4xl font-bold">
              {{ t('login.welcome') }} 👋🏻
            </h1>
          </Motion>
          <el-form
            ref="loginFormRef"
            :rules="loginRules"
            size="large"
            :model="loginForm"
          >
            <Motion :delay="100" direction="right">
              <el-form-item
                :rules="[
                  {
                    required: true,
                    message: t('login.usernameEmpty'),
                    trigger: 'blur'
                  }
                ]"
                prop="name"
              >
                <el-input
                  v-model="loginForm.name"
                  :prefix-icon="User"
                  clearable
                  :placeholder="t('login.username')"
                />
              </el-form-item>
            </Motion>

            <Motion :delay="150" direction="right">
              <el-form-item prop="password">
                <el-input
                  v-model="loginForm.password"
                  :prefix-icon="Lock"
                  clearable
                  show-password
                  :placeholder="t('login.password')"
                />
              </el-form-item>
            </Motion>

            <Motion :delay="200" direction="right">
              <el-form-item prop="verifyCode">
                <el-input
                  v-model="loginForm.verifyCode"
                  :prefix-icon="Odometer"
                  clearable
                  :placeholder="t('login.verfication')"
                >
                  <template v-slot:append>
                    <ReImageVerify v-model:code="imgCode" />
                  </template>
                </el-input>
              </el-form-item>
            </Motion>

            <Motion :delay="250" direction="right">
              <el-form-item>
                <div class="w-full h-[20px] flex justify-between items-center">
                  <el-checkbox
                    v-model="loginForm.expiresInDays"
                    :true-value="7"
                    :false-value="1"
                  >
                    {{ t('login.remember') }}
                    <el-popover
                      placement="top"
                      :width="300"
                      trigger="hover"
                      :content="t('login.rememberTip')"
                    >
                      <template #reference>
                        <el-icon class="align-middle"><InfoFilled /></el-icon>
                      </template>
                    </el-popover>
                  </el-checkbox>
                  <el-button link type="primary">
                    {{ t('login.forget') }}
                  </el-button>
                </div>
                <el-button
                  class="w-full mt-4"
                  size="default"
                  type="primary"
                  :loading="loading"
                  :disabled="disabled"
                  @click="onLogin(loginFormRef)"
                >
                  {{ t('login.login') }}
                </el-button>
              </el-form-item>
            </Motion>

            <Motion :delay="300" direction="right">
              <el-form-item>
                <div class="w-full h-[20px] flex justify-between items-center">
                  <el-button
                    v-for="(item, index) in operates"
                    :key="index"
                    class="w-full mt-4"
                    size="default"
                  >
                    {{ t(item.title) }}
                  </el-button>
                </div>
              </el-form-item>
            </Motion>

            <Motion :delay="350" direction="right">
              <el-form-item>
                <el-divider>
                  <p class="text-gray-500 text-xs">{{ t('login.anther') }}</p>
                </el-divider>
                <div class="w-full flex justify-evenly">
                  <span
                    v-for="(item, index) in thirdParty"
                    :key="index"
                    :title="t(item.title)"
                  >
                    <i
                      :class="`icon-${item.icon}`"
                      class="text-2xl cursor-pointer text-gray-500 hover:text-blue-400"
                    />
                  </span>
                </div>
              </el-form-item>
            </Motion>

            <Motion :delay="400" direction="right">
              <div class="text-center mt-8 text-gray-500 text-sm">
                {{ t('login.withoutAccount') }}
                <span class="easy-link">{{ t('login.createAccount') }}</span>
              </div>
            </Motion>
          </el-form>
        </div>
      </div>
    </div>

    <div
      class="w-full flex-c absolute bottom-3 text-sm text-[rgba(0,0,0,0.6)] dark:text-[rgba(220,220,242,0.8)]"
    >
      Copyright © 2024-present
      <a class="hover:text-primary" href="" target="_blank"> &nbsp; </a>
      Easy Admin
    </div>
  </div>
</template>

<style lang="scss" scoped>
.easy-bg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  margin-left: -44%;
  overflow: hidden;
  content: '';
  background-repeat: no-repeat;
  background-position: 100%;
  background-size: auto 100%;

  .re-svg {
    position: absolute;
    top: 0;
    right: 0;
  }
}

.login-tool {
  padding: 2px 14px;
  background-color: var(--easy-tool-color);
  border-radius: 24px;

  .color-picker {
    overflow: hidden;

    .color-box {
      display: flex;
      align-items: center;
      width: 0;
      overflow: hidden;
      transition: all var(--easy-transition-duration);
    }

    .color-box > span {
      position: relative;
      display: inline-block;
      flex-shrink: 0;
      width: 20px;
      height: 20px;
      margin: 0 8px;
      cursor: pointer;
      border-radius: 50%;
    }

    .icon-check::before {
      position: absolute;
      top: 50%;
      left: 50%;
      font-size: 16px;
      color: #f8fafc;
      transform: translate(-50%, -50%);
    }
  }

  .color-picker:hover > .color-box {
    width: v-bind('themeWidth');
  }
}

[class*='icon-'] {
  font-size: 20px;

  &:hover {
    color: var(--el-color-primary);
  }
}

.easy-logo {
  font-size: 24px;
  font-weight: 700;
  color: #f8fafc;
}

.login-container {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-gap: 18rem;
  width: 100vw;
  max-width: 100%;
  height: 100vh;
  padding: 0 2rem;
}

.login-illustration {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
}

.login-box {
  display: flex;
  align-items: center;
  padding-left: 40px;
  overflow: hidden;
  text-align: center;
}

:deep(.el-input-group__append) {
  padding: 0;
}

.icon-color:hover ~ .color-picker {
  left: -100%;
  width: 200px;
}

:deep(.el-button) {
  height: 38px;
}
</style>
